package com.support.android.myapp3.util;

import com.support.android.myapp3.domain.BXEnum;

import java.util.LinkedHashMap;
import java.util.Map;

public class TaxCalc {
    /**
     * 上海
     * 社保缴费基数的上限设定在上一年度全市职工月平均工资的300%，下限为上一年度全市职工月平均工资的60%
     * 住房公积金的缴存基数不得超过本市上一年度在岗职工月平均工资的3倍,住房公积金的缴存基数不得低于本市上一年度最低月工资标准
     **/

    private Money avgSalary;
    private Money minSalary;

    private Money maxLimitMoney;
    private Money minLimitMoney;

    private Money money;
    private Money shebaoMoneyCalc;
    private Money gongjijinMoneyCalc;
    private Money baoxianPersonMoney;
    private Money baoxianCompanyMoney;
    private Money afterBaoxianMoney;
    private Money lastPMoney;
    private Money lastCMoney;

    private PersonTax personTax;

    private Map<String,PublicTaxCalc> taxMap;

    public TaxCalc(String money) {
        //sh 2018
        this(money,"7132","2300");
    }

    public TaxCalc(String money, String avgSalaryYStr, String mixSalaryYStr) {
        this.avgSalary = Money.instanceYuan(avgSalaryYStr);
        this.minSalary = Money.instanceYuan(mixSalaryYStr);
        this.money = Money.instanceYuan(money);

        init();
    }

    private void init() {
        maxLimitMoney = avgSalary.multiplyNum("3");
        minLimitMoney = avgSalary.divideNum("0.6");

        if (this.money.getFen() > maxLimitMoney.getFen()) {
            this.shebaoMoneyCalc = maxLimitMoney;
        } else if (this.money.getFen() < minLimitMoney.getFen()) {
            this.shebaoMoneyCalc = minLimitMoney;
        } else {
            this.shebaoMoneyCalc = money;
        }

        if (this.money.getFen() > maxLimitMoney.getFen()) {
            this.gongjijinMoneyCalc = maxLimitMoney;
        } else if (this.money.getFen() < minSalary.getFen()) {
            this.gongjijinMoneyCalc = minSalary;
        } else {
            this.gongjijinMoneyCalc = money;
        }

        taxMap = new LinkedHashMap<>();
        taxMap.put(BXEnum.YANG_LAO.getName(),new PublicTaxCalc("养老保险", shebaoMoneyCalc, "8", "20"));
        taxMap.put(BXEnum.YI_LIAO.getName(),new PublicTaxCalc("医疗保险", shebaoMoneyCalc, "2", "9.5"));
        taxMap.put(BXEnum.SHI_YE.getName(),new PublicTaxCalc("失业保险", shebaoMoneyCalc, "0.5", "0.5"));
        taxMap.put(BXEnum.GONG_SHANG.getName(),new PublicTaxCalc("工伤保险", shebaoMoneyCalc, "0", "0.5"));
        taxMap.put(BXEnum.SHENG_YU.getName(),new PublicTaxCalc("生育保险", shebaoMoneyCalc, "0", "1"));
        taxMap.put(BXEnum.ZHU_FANG.getName(),new PublicTaxCalc("住房公积金", gongjijinMoneyCalc, "7", "7"));

        baoxianPersonMoney = Money.instanceFen("0");
        baoxianCompanyMoney = Money.instanceFen("0");

        for (Map.Entry<String, PublicTaxCalc> entry : taxMap.entrySet()) {
            baoxianPersonMoney = baoxianPersonMoney.addMoney(entry.getValue().calcPersonTax());
            baoxianCompanyMoney = baoxianCompanyMoney.addMoney(entry.getValue().calcCompanygTax());
        }

        afterBaoxianMoney = money.subtractMoney(baoxianPersonMoney);
        personTax = new PersonTax("个人所得税", afterBaoxianMoney);
        lastPMoney = afterBaoxianMoney.subtractMoney(personTax.calcTax());
        lastCMoney = money.addMoney(baoxianCompanyMoney);
    }

    public class PublicTaxCalc {
        public String name;
        public String personPer;
        public String companyPer;
        public Money money;

        public PublicTaxCalc(String name, String personPerStr, String companyPerStr) {
            this.name = name;
            this.personPer = personPerStr;
            this.companyPer = companyPerStr;
        }

        public PublicTaxCalc(String name, String moneyYuan, String personPerStr, String companyPerStr) {
            this(name, personPerStr, companyPerStr);
            this.money = Money.instanceYuan(moneyYuan);
        }

        public PublicTaxCalc(String name, Money money, String personPerStr, String companyPerStr) {
            this(name, personPerStr, companyPerStr);
            this.money = money;
        }

        public Money calcPersonTax() {
            return money.multiplyPercentage(personPer);
        }

        public Money calcCompanygTax() {
            return money.multiplyPercentage(companyPer);
        }

        public String calcPersonTaxStr() {
            return calcPersonTax().getYuan();
        }

        public String calcCompanygTaxStr() {
            return calcCompanygTax().getYuan();
        }

        public String getName() {
            return name;
        }

        public String getPersonPer() {
            return personPer;
        }

        public String getCompanyPer() {
            return companyPer;
        }

        public Money getMoney() {
            return money;
        }
    }

    public class PersonTax {
        private String name;
        private Money money;

        public PersonTax(String name, Money money) {
            this.name = name;
            this.money = money;
        }

        public Money calcTax() {
            return TaxCalc.calcPersonTax(money);
        }

        public String getName() {
            return name;
        }
    }

    public static Money calcPersonTax(Money money) {

        if (money.getFen() <= 500000) {
            return Money.instanceFen("0");
        }

        money = money.subtractFen("500000");
        money.cacheFen();

        if (money.getCacheFen() <= 300000) {
            return money.multiplyNum("0.03");
        }

        if (money.getCacheFen() > 300000 && money.getCacheFen() <= 1200000) {
            return money.multiplyNum("0.1").subtractYuan("210");
        }

        if (money.getCacheFen() > 1200000 && money.getCacheFen() <= 2500000) {
            return money.multiplyNum("0.2").subtractYuan("1410");
        }

        if (money.getCacheFen() > 2500000 && money.getCacheFen() <= 3500000) {
            return money.multiplyNum("0.25").subtractYuan("2660");
        }

        if (money.getCacheFen() > 3500000 && money.getCacheFen() <= 5500000) {
            return money.multiplyNum("0.30").subtractYuan("4410");
        }

        if (money.getCacheFen() > 5500000 && money.getCacheFen() <= 8000000) {
            return money.multiplyNum("0.35").subtractYuan("7160");
        }

        if (money.getCacheFen() > 8000000) {
            return money.multiplyNum("0.45").subtractYuan("15160");
        }

        return Money.instanceFen("0");
    }

    public Money getAvgSalary() {
        return avgSalary;
    }

    public Money getMinSalary() {
        return minSalary;
    }

    public Money getMaxLimitMoney() {
        return maxLimitMoney;
    }

    public Money getMinLimitMoney() {
        return minLimitMoney;
    }

    public Money getMoney() {
        return money;
    }

    public Money getShebaoMoneyCalc() {
        return shebaoMoneyCalc;
    }

    public Money getGongjijinMoneyCalc() {
        return gongjijinMoneyCalc;
    }

    public Money getBaoxianPersonMoney() {
        return baoxianPersonMoney;
    }

    public Money getBaoxianCompanyMoney() {
        return baoxianCompanyMoney;
    }

    public Money getLastPMoney() {
        return lastPMoney;
    }

    public Money getLastCMoney() {
        return lastCMoney;
    }

    public Map<String, PublicTaxCalc> getTaxMap() {
        return taxMap;
    }

    public PersonTax getPersonTax() {
        return personTax;
    }

    public Money getAfterBaoxianMoney() {
        return afterBaoxianMoney;
    }
}
